package com.kuangjia.student_ems.service.impl;

import com.kuangjia.student_ems.dto.request.CreateNotificationRequest;
import com.kuangjia.student_ems.dto.response.NotificationResponse;
import com.kuangjia.student_ems.entity.Notification;
import com.kuangjia.student_ems.entity.User;
import com.kuangjia.student_ems.exception.NotificationException;
import com.kuangjia.student_ems.repository.NotificationRepository;
import com.kuangjia.student_ems.repository.UserRepository;
import com.kuangjia.student_ems.service.NotificationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class NotificationServiceImpl implements NotificationService {
    @Autowired
    private NotificationRepository notificationRepository;
    
    @Autowired
    private UserRepository userRepository;

    @Override
    public NotificationResponse createNotification(CreateNotificationRequest request) {
        // 验证消息类型
        validateNotificationType(request.getType());
        
        // 如果指定了用户ID，验证用户是否存在
        if (request.getUserId() != null) {
            if (!userRepository.existsById(request.getUserId())) {
                throw new NotificationException("指定的用户不存在");
            }
        }
        
        // 创建通知实体
        Notification notification = new Notification();
        notification.setUserId(request.getUserId());
        notification.setType(request.getType());
        notification.setTitle(request.getTitle());
        notification.setContent(request.getContent());
        notification.setIsRead(false);
        notification.setCreateTime(LocalDateTime.now());
        
        // 保存到数据库
        Notification savedNotification = notificationRepository.save(notification);
        
        // 转换为响应DTO
        return convertToResponse(savedNotification);
    }
    
    @Override
    public List<NotificationResponse> createNotificationsForUsers(CreateNotificationRequest request, List<Long> userIds) {
        // 验证消息类型
        validateNotificationType(request.getType());
        
        // 验证所有用户是否存在
        for (Long userId : userIds) {
            if (!userRepository.existsById(userId)) {
                throw new NotificationException("用户ID " + userId + " 不存在");
            }
        }
        
        List<Notification> notifications = new ArrayList<>();
        LocalDateTime now = LocalDateTime.now();
        
        // 为每个用户创建通知
        for (Long userId : userIds) {
            Notification notification = new Notification();
            notification.setUserId(userId);
            notification.setType(request.getType());
            notification.setTitle(request.getTitle());
            notification.setContent(request.getContent());
            notification.setIsRead(false);
            notification.setCreateTime(now);
            notifications.add(notification);
        }
        
        // 批量保存
        List<Notification> savedNotifications = notificationRepository.saveAll(notifications);
        
        // 转换为响应DTO列表
        return savedNotifications.stream()
                .map(this::convertToResponse)
                .collect(Collectors.toList());
    }
    
    @Override
    public List<NotificationResponse> createSystemNotification(CreateNotificationRequest request) {
        // 验证消息类型
        validateNotificationType(request.getType());
        
        // 创建系统消息（user_id为null，所有用户可见）
        Notification notification = new Notification();
        notification.setUserId(null); // 系统消息user_id为null
        notification.setType(request.getType());
        notification.setTitle(request.getTitle());
        notification.setContent(request.getContent());
        notification.setIsRead(false);
        notification.setCreateTime(LocalDateTime.now());
        
        // 保存到数据库
        Notification savedNotification = notificationRepository.save(notification);
        
        // 转换为响应DTO列表
        return List.of(convertToResponse(savedNotification));
    }
    
    // 验证消息类型
    private void validateNotificationType(String type) {
        List<String> validTypes = List.of("system", "approval", "salary", "ai", "profile");
        if (!validTypes.contains(type)) {
            throw new NotificationException("无效的消息类型: " + type + "。有效类型: " + validTypes);
        }
    }
    
    // 转换为响应DTO
    private NotificationResponse convertToResponse(Notification notification) {
        return new NotificationResponse(
            notification.getId(),
            notification.getUserId(),
            notification.getType(),
            notification.getTitle(),
            notification.getContent(),
            notification.getLink(),
            notification.getIsRead(),
            notification.getCreateTime()
        );
    }

    @Override
    public Page<Notification> getNotifications(User currentUser, Long userId, Boolean isRead, String keyword, Pageable pageable) {
        // 权限检查：只有管理员可以查看其他用户的消息
        if (!currentUser.getRole().equals(User.UserRole.HR_ADMIN) && !userId.equals(currentUser.getId())) {
            throw new NotificationException("权限不足，无法查看其他用户的消息");
        }
        
        if (StringUtils.hasText(keyword)) {
            // 有搜索关键词
            if (isRead == null) {
                return notificationRepository.findByUserIdOrSystemMessageAndKeyword(userId, keyword, pageable);
            } else {
                return notificationRepository.findByUserIdOrSystemMessageAndIsReadAndKeyword(userId, isRead, keyword, pageable);
            }
        } else {
            // 无搜索关键词
            if (isRead == null) {
                return notificationRepository.findByUserIdOrSystemMessage(userId, pageable);
            } else {
                return notificationRepository.findByUserIdOrSystemMessageAndIsRead(userId, isRead, pageable);
            }
        }
    }

    @Override
    @Transactional
    public void markAsRead(User currentUser, List<Long> ids) {
        List<Notification> notifications = notificationRepository.findAllById(ids);
        
        // 权限检查：只有管理员可以标记其他用户的消息为已读，但用户可以标记系统消息
        for (Notification notification : notifications) {
            if (!currentUser.getRole().equals(User.UserRole.HR_ADMIN) && 
                notification.getUserId() != null && 
                !notification.getUserId().equals(currentUser.getId())) {
                throw new NotificationException("权限不足，无法标记其他用户的消息为已读");
            }
        }
        
        for (Notification n : notifications) {
            n.setIsRead(true);
        }
        notificationRepository.saveAll(notifications);
    }

    @Override
    @Transactional
    public void deleteNotifications(User currentUser, List<Long> ids) {
        List<Notification> notifications = notificationRepository.findAllById(ids);
        
        // 权限检查：只有管理员可以删除其他用户的消息，但用户可以删除系统消息
        for (Notification notification : notifications) {
            if (!currentUser.getRole().equals(User.UserRole.HR_ADMIN) && 
                notification.getUserId() != null && 
                !notification.getUserId().equals(currentUser.getId())) {
                throw new NotificationException("权限不足，无法删除其他用户的消息");
            }
        }
        
        notificationRepository.deleteAllById(ids);
    }

    @Override
    public Long countUnread(User currentUser, Long userId) {
        // 权限检查：只有管理员可以查看其他用户的未读消息数量
        if (!currentUser.getRole().equals(User.UserRole.HR_ADMIN) && !userId.equals(currentUser.getId())) {
            throw new NotificationException("权限不足，无法查看其他用户的未读消息数量");
        }
        
        return notificationRepository.countByUserIdOrSystemMessageAndIsRead(userId, false);
    }
} 